1. /* sdfdpow.cpp by K.Tsuru */
  2. // funcion ID 3018 DARDIX, BRADIX(n > 0)
  3. /*********************************************************
  4. SDouble class x^n
  5. Provides x to the n-th power using Knuth's binary method.
  6. For n > 0 it allows to hand a SDecimal object x.
  7. *********************************************************/
  8. #ifndef SN_H
  9. #include "sn.h"
  10. #endif
  11. static const char* const func = "Dpow";
  12. SDouble Dpow(const SDouble& x, long n){
  13. if( (x.Type() == x.BIN_DEC) && (n < 0) ) x.SetError(x.RADIX_ERR, func, 3018);
  14. if(x.Sign(3018) == 0) return x;
  15. SDouble one(x.Type(), 0);
  16. one = 1.0;
  17. int ix;
  18. if((ix = x.IsOne()) != 0){ //|x| = 1.0
  19. if( (ix < 0) && (labs(n) & 1) ) one.ChangeSign(); // x = -1
  20. return one;
  21. }
  22. if(!n) return one;
  23. else if(n == 1L) return x;
  24. else if(n == -1L) return DReciprocal(x); // 1/x
  25. // Check the condition "x^n < DRADIX^DRADIXEXP_MAX"
  26. double expR = (double)n*x.NetRdxExp()/(double)DFIGURES; // exponent of result
  27. if(fabs(expR) > DRADIX_EXP_MAX){
  28. if(expR > 0) x.SetError(x.OVERFLOW_ERR, func, 3018);
  29. x.SetError(x.UNDERFLOW_ERR, func, -3018);
  30. return 0.0;
  31. }
  32. /*************************************************************************
  33. The methods for the calculation of x^n (n < 0).
  34. method 1:Firstly let y = 1/x, and evaluates y^|n|.
  35. method 2:Firstly y = x^|n|, and evaluates 1/y.
  36. When x has many figures both method have same speed. But about the accuracy
  37. the method 1 has an advantage because the error of reciprocal in last few
  38. figures is excluded by multiplication.
  39. When x has small figures the method 2 has an advantage in speed because
  40. x^|n| can be evaluated rapidly.But to get a finite decimal such as 1/(2^10)
  41. exactly a rounding off is necessary."DReciprocal" includes this procedure.
  42. In evaluating 3^(-100) the method 2 is faster about eight times.
  43. ***************************************************************************/
  44. long m = labs(n);
  45. SDouble y(one), z(x.Type(), 0);
  46. int retRecY = 0; // return 1/y ?
  47. if(n < 0){ // Type() != BIN_DEC
  48. if(x.Last() - x.First() <= 5u){
  49. retRecY = 1; z = x; //small figures
  50. } else z = DReciprocal(x); // 1/x
  51. }else z = x;
  52. while(y.Sign(3018)){
  53. if(m % 2) y *= z;
  54. m /= 2;
  55. if( !m ) break;
  56. z *= z;
  57. }
  58. if(retRecY){
  59. y = DReciprocal(y); // 1/y
  60. }
  61. return y;
  62. }

sdfdpow.cpp : last modifiled at 2015/12/03 21:38:14(2,326 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).